package cn.xttc.edu.controller;

import cn.xttc.edu.entity.*;
import cn.xttc.edu.entity.vo.OrderVo;
import cn.xttc.edu.entity.vo.RuleVo;
import cn.xttc.edu.service.*;
import cn.xttc.edu.util.HttpUtils;
import cn.xttc.edu.util.MyUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpSession;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 处理用户请求
 *
 * @author yl
 */
@RestController
@RequestMapping("/wx")
public class WxCustomerController {
    private static final String APPID = "wx0592a476cf49a60c";
    private static final String SECRET = "9e874592d4d2372248113f07d404193a";

    @Autowired
    private ExpenseRuleService ruleService;
    @Autowired
    private CustomerService customerService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private CarService carService;
    @Autowired
    CarTypeService carTypeService;

    /**
     * 获取openid
     *
     * @param code code
     * @return openid
     */
    @PostMapping("/getOpenId")
    public String getOpenId(@RequestParam("code") String code, HttpSession session) {
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + APPID + "&secret=" + SECRET + "&code=" + code + "&grant_type=authorization_code";
        String s = HttpUtils.sendGet(url);
        String openid = JSON.parseObject(s).getString("openid");
        session.setAttribute("openid", openid);
        return openid;
    }

    /**
     * 获取订单价格
     *
     * @param typeId   货车类型id
     * @param distance 距离
     * @return 价格字符串
     */
    @GetMapping("/order_price")
    public String getOrderPrice(@RequestParam("typeId") Integer typeId,
                                @RequestParam("distance") Double distance) {
        ExpenseRule rule = ruleService.getOne(new QueryWrapper<ExpenseRule>().eq("type_id", typeId));
        return MyUtil.getOrderPrice(rule, distance).stripTrailingZeros().toPlainString();
    }

    /**
     * 根据类型id查询规则对象
     *
     * @param typeId 类型id
     * @return 包装对象
     */
    @GetMapping("/rule")
    public ReturnMsg getRuleByTypeId(@RequestParam("typeId") Integer typeId) {
        RuleVo ruleVo = ruleService.getOneByTypeId(typeId);
        return ReturnMsg.success(ruleVo);
    }

    /**
     * 处理用户的支付下单
     *
     * @param name            用户姓名
     * @param phone           用户联系方式
     * @param typeId          货车类型id
     * @param startPoint      起点
     * @param endPoint        终点
     * @param appointmentTime 预约时间
     * @param remark          订单备注
     * @param distance        距离
     */
    @PostMapping("/pay")
    public ReturnMsg handlePay(
            @RequestParam("name") String name,
            @RequestParam("phone") String phone,
            @RequestParam("openid") String openid,
            @RequestParam("typeId") Integer typeId,
            @RequestParam("startPoint") String startPoint,
            @RequestParam("endPoint") String endPoint,
            @RequestParam("appointmentTime") String appointmentTime,
            @RequestParam(value = "remark", required = false, defaultValue = "") String remark,
            @RequestParam("distance") Double distance,
            @RequestParam("price") String price
    ) {
        //判断openid是否为空，为空说明不是由微信公众号进入添加，为模拟测试用户，给一个随机的openid
        if ("".equals(openid)) {
            openid = UUID.randomUUID().toString().replace("-", "");
        }

        //订单价格转为BigDecimal类型
        BigDecimal orderPrice = new BigDecimal(price.trim());

        //定义一个变量保存客户id
        int id;
        //根据openid查询客户
        Customer one = customerService.getOne(new QueryWrapper<Customer>().eq("open_id", openid));
        if (one != null) {
            id = one.getId();
            //客户存在，判断手机号是否需要更改，并修改账户余额
            if (!phone.equals(one.getPhone())) {
                customerService.updateById(one.setPhone(phone));
            }
            customerService.updateById(one.setAccount(one.getAccount().subtract(orderPrice)));
        } else {
            //客户不存在，添加客户，初始余额为10000
            Customer customer = new Customer().setName(name).setPhone(phone).setOpenId(openid).setAccount(BigDecimal.valueOf(10000).subtract(orderPrice));
            customerService.save(customer);
            id = customer.getId();
        }

        //生成订单号,判断是否存在
        String orderId;
        do {
            orderId = MyUtil.getOrderId();
        } while (orderService.getById(orderId) != null);

        //按类型随机分配空闲状态的车辆
        List<Car> list = carService.list(new QueryWrapper<Car>().eq("type_id", typeId).eq("status", 0));
        int n = new Random().nextInt(list.size());
        Car car = list.get(n);

        //添加订单
        Order order = new Order().
                setId(orderId).
                setCId(id).
                setAppointmentTime(LocalDateTime.parse(appointmentTime)).
                setStartPoint(startPoint.replace("/", "")).
                setEndPoint(endPoint.replace("/", "")).
                setDistance(distance).
                setRemark(remark).
                setPrice(orderPrice).
                setCarId(car.getId());
        orderService.save(order);

        //更改车辆状态为工作中
        carService.updateById(car.setStatus(1));

        return ReturnMsg.success("添加成功");
    }

    /**
     * 获取订单
     *
     * @param openid   用户的openid
     * @param statuses 订单状态
     * @return 包装对象
     */
    @GetMapping("/customer/order")
    public ReturnMsg getOrdersByStatus(
            @RequestParam("openid") String openid,
            @RequestParam("statuses[]") Integer[] statuses
    ) {
        Customer customer = customerService.getOne(new QueryWrapper<Customer>().eq("open_id", openid));
        if (customer != null) {
            List<OrderVo> orders = orderService.getOrdersByCIdAndStatus(customer.getId(), statuses);
            return ReturnMsg.success(orders);
        } else {
            return ReturnMsg.fail("");
        }
    }

    /**
     * 根据id和状态获取订单
     *
     * @param order order
     * @return 包装对象
     */
    @GetMapping("/customer/order/{id}")
    public ReturnMsg getOrderById(Order order) {
        IPage<OrderVo> page = orderService.getOrderVosByCondition(new Page<>(1, 1), order.getStatus(), order.getId());
        return ReturnMsg.success(page.getRecords().get(0));
    }

    /**
     * 获取所有汽车类型
     *
     * @return 包装对象
     */
    @GetMapping("/carType")
    public ReturnMsg getAll() {
        List<CarType> list = carTypeService.list();
        if (!list.isEmpty()) {
            return ReturnMsg.success(list);
        } else {
            return ReturnMsg.fail(null);
        }
    }

    /**
     * 取消订单
     *
     * @param id 订单号
     * @return 包装对象
     */
    @PutMapping("/customer/order/{id}")
    public ReturnMsg cancelOrder(@PathVariable("id") String id) {
        Order order = orderService.getById(id);
        order.setStatus(3);
        orderService.updateById(order);
        //更新车辆状态
        carService.update(new UpdateWrapper<Car>().eq("id", order.getCarId()).set("status", 0));
        return ReturnMsg.success("取消成功");
    }
}
